package com.example.myandroidapp1.gateway.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

import com.example.myandroidapp1.gateway.HttpRestGateway;

public class HttpRestGatewayImpl implements HttpRestGateway {

	@Override
	public String makePostCall(String url, Map<String, String> requestParameters) {
		HttpMethod httpMethod = createPostHttpMethod(url, requestParameters);
		return executeRequest((PostMethod) httpMethod);
	}

	@Override
	public String makeGetCall(String url, Map<String, String> requestParameters) {
		HttpMethod httpMethod = createGetHttpMethod(url, requestParameters);
		return executeRequest((GetMethod) httpMethod);
	}

	private HttpMethod createGetHttpMethod(String url,
			Map<String, String> requestParameters) {
		GetMethod getMethod = new GetMethod(url);
		return getMethod;
	}

	/**
	 * This method takes PostMethod as an input and execute the Http Post
	 * request call
	 * 
	 * @param httpMethod
	 *            - Represents the PostMethod
	 * @return - String
	 */
	private String executeRequest(HttpMethod httpMethod) {
		try {
			HttpClient client = new HttpClient();
			int returnCode = client.executeMethod(httpMethod);
			InputStream is = httpMethod.getResponseBodyAsStream();
			String str = convertStreamToString(is);
			return str;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			httpMethod.releaseConnection();
		}
		return null;

	}
	
	

	/**
	 * This method creates the returns an instance of HttpMethod which uses the
	 * URL and request parameters.
	 * 
	 * @param url
	 *            - Represents the URL string
	 * @param requestParameters
	 *            - Represents the request parameter map
	 * @return - HttpMethod
	 */
	private HttpMethod createPostHttpMethod(String url,
			Map<String, String> requestParameters) {
		PostMethod httpMethod = new PostMethod(url);
		for (NameValuePair nameValuePair : getPostParamList(requestParameters)) {
			httpMethod.addParameter(nameValuePair);
		}
		return httpMethod;
	}

	/**
	 * This method generates the list of name value pair for Http Post Request.
	 * 
	 * @param requestParameters
	 *            - Represents the map of request parameters.
	 * 
	 * @return - List<NameValuePair>
	 */
	private List<NameValuePair> getPostParamList(
			Map<String, String> requestParameters) {
		List<NameValuePair> postParamList = new ArrayList<NameValuePair>();
		for (Entry<String, String> entry : requestParameters.entrySet()) {
			postParamList.add(new NameValuePair(entry.getKey(), entry
					.getValue()));
		}
		return postParamList;
	}

	/**
	 * To convert the InputStream to String we use the Reader.read(char[]
	 * buffer) method. We iterate until the Reader return -1 which means there's
	 * no more data to read. We use the StringWriter class to produce the
	 * string.
	 */
	private String convertStreamToString(InputStream is) throws IOException {
		if (is != null) {
			Writer writer = new StringWriter();
			char[] buffer = new char[1024];
			try {
				Reader reader = new BufferedReader(new InputStreamReader(is,
						"UTF-8"));
				int n;
				while ((n = reader.read(buffer)) != -1) {
					writer.write(buffer, 0, n);
				}
			} finally {
				is.close();
			}
			return writer.toString();
		} else {
			return "";
		}
	}

}
